package com.jelly.web.modules.staff.user.service.impl;

import com.jelly.common.constant.CodeConstant;
import com.jelly.common.constant.Constant;
import com.jelly.common.exception.UploadImgException;
import com.jelly.common.util.ListUtil;
import com.jelly.common.util.back.ShiroUtil;
import com.jelly.common.util.StringUtils;
import com.jelly.common.util.web.BuildTreeUtil;
import com.jelly.common.util.web.RequestContextHolderUtil;
import com.jelly.common.web.tree.Tree;
import com.jelly.config.shiro.token.TokenUtil;
import com.jelly.web.modules.basics.dictionary.domain.Dictionary;
import com.jelly.web.modules.basics.dictionary.domain.DiyTypeAndDictionary;
import com.jelly.web.modules.basics.dictionary.service.IDiyTypeAndDictionaryService;
import com.jelly.web.modules.system.permission.domain.Permission;
import com.jelly.web.modules.system.permission.service.IPermissionService;
import com.jelly.web.modules.system.role.domain.Role;
import com.jelly.web.modules.system.role.service.IRoleService;
import com.jelly.web.modules.system.role.service.IUserRoleService;
import com.jelly.web.modules.staff.user.dao.UserAndRoleAndPermissionMapper;
import com.jelly.web.modules.staff.user.dao.UserMapper;
import com.jelly.web.modules.staff.user.domain.*;
import com.jelly.web.modules.staff.user.service.IUserService;
import com.jelly.web.share.upload.service.IUploadService;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.pam.UnsupportedTokenException;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @创建人 ql
 * @创建时间 2018-08-17 10:40
 * @项目名称 jelly
 * @功能描述: 用户接口实现类
 **/
@Service
public class UserServiceImpl implements IUserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserAndRoleAndPermissionMapper userAndRoleAndPermissionMapper;

    @Autowired
    private IRoleService roleService;

    @Autowired
    private IPermissionService permissionService;

    @Autowired
    private IDiyTypeAndDictionaryService diyTypeAndDictionaryService;

    @Autowired
    private IUserRoleService userRoleService;

    @Autowired
    private IUploadService uploadService;

    /**
     * 条件查询用户信息
     * @param example
     * @return
     */
    @Override
    public List<User> getUser(UserExample example) {
        return userMapper.selectByExample(example);
    }

    /**
     * 主键查询用户信息
     * @param userId
     * @return
     */
    @Override
    public User getUser(String userId) {
        return userMapper.selectByPrimaryKey(userId);
    }

    /**
     * 新增用户信息
     * @param user
     * @return
     */
    @Override
    public boolean addUser(User user) {

        String id = UUID.randomUUID().toString().replaceAll("-", "");
        user.setUserId(id);

        Object result = new SimpleHash("MD5",user.getPassword(),id,1);
        user.setPassword(result.toString());

        userRoleService.addUserRole(id,user.getMenuIds());
        user.setAddDate(new Date());
        user.setLoginCount(0);
        if(StringUtils.isBlank(user.getImg())){
            user.setImg("/img/user/photo_s.jpg");
        }
        if(StringUtils.isBlank(user.getNickname())){
            user.setNickname(id);
        }
        return userMapper.insertSelective(user) > 0;

    }

    /**
     * 删除用户信息（并删除用户角色关联）
     * @param userId
     * @return
     */
    @Override
    public boolean delectUser(String userId) {
        userRoleService.delectUserRole(userId);
        return userMapper.deleteByPrimaryKey(userId) > 0;
    }
    /**
     * 批量删除用户信息（并删除用户角色关联）
     * @param userId
     * @return
     */
    @Override
    public boolean delectsUser(List<String> userId) {
        userRoleService.delectsUserRole(userId);
        UserExample example = new UserExample();
        example.createCriteria().andUserIdIn(userId);
        return userMapper.deleteByExample(example) > 0;
    }
    /**
     * 通过登陆账号查询用户信息
     * @param loginAccount
     * @return
     */
    @Override
    public User getLoginAccount(String loginAccount) {
        UserExample example = new UserExample();
        example.createCriteria().andLoginAccountEqualTo(loginAccount);
        List<User> list = userMapper.selectByExample(example);
        if(ListUtil.isNotList(list)){
            return list.get(0);
        }
        return null;
    }

    /**
     * 获取所有用户信息
     * @param user
     * @return
     */
    @Override
    public List<User> getUser(User user) {

        UserExample example = new UserExample();
        UserExample.Criteria criteria = example.createCriteria();

        if(StringUtils.isNotBlank(user.getLoginAccount())){
            criteria.andLoginAccountEqualTo(user.getLoginAccount());
        }
        if(StringUtils.isNotBlank(user.getMobile())){
            criteria.andMobileEqualTo(user.getMobile());
        }
        if(StringUtils.isNotBlank(user.getIsState())){
            criteria.andIsStateEqualTo(user.getIsState());
        }
        if(StringUtils.isNotBlank(user.getIsState())){
            criteria.andIsStateEqualTo(user.getIsState());
        }
        if(ListUtil.isNotList(user.getDeptIds())){
            criteria.andDeptIdIn(user.getDeptIds());
        }
        if(StringUtils.isNotBlank(user.getStartTime()) && StringUtils.isNotBlank(user.getEndTime())){
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            try{
                criteria.andAddDateGreaterThanOrEqualTo(sdf.parse(user.getStartTime()));
                criteria.andAddDateLessThanOrEqualTo(sdf.parse(user.getEndTime()));
            }catch (Exception e){

            }
        }

        return userMapper.selectByExample(example);

    }

    /**
     * 通过登陆账号查询用户信息
     * @param loginAccount
     * @return
     */
    @Override
    public User getLoginAccount(String loginAccount, String password) {

        if(null != RequestContextHolderUtil.getRequest().getAttribute(CodeConstant.GIFCODE)){

            RequestContextHolderUtil.getRequest().removeAttribute(CodeConstant.GIFCODE);
            throw new UnsupportedTokenException("验证码错误");

        }

        UserExample example = new UserExample();

        example.createCriteria().andLoginAccountEqualTo(loginAccount);

        List<User> list = userMapper.selectByExample(example);

        User user = null;

        if(ListUtil.isNotList(list)){

            user = list.get(0);

            //账号状态，是否可登陆
            if(Constant.ERROR.equals(user.getIsState())){

                throw new DisabledAccountException("帐号已经禁止登录");

            }

        }

        if(null == user){

            throw new UnknownAccountException("账号不存在");

        }

        return user;

    }

    /**
     * 主键修改用户信息
     * @param user
     * @return
     */
    @Override
    public boolean updateUser(User user) {
        if(StringUtils.isNotBlank(user.getBaseId())){
            user.setUserId(user.getBaseId());
        }
        if(ListUtil.isNotList(user.getMenuIds())){
            userRoleService.delectUserRole(user.getUserId());
            userRoleService.addUserRole(user.getUserId(),user.getMenuIds());
        }

        boolean bol = userMapper.updateByPrimaryKeySelective(user) > 0;
        if(bol){
            if(Constant.ERROR.equals(user.getIsState())){
                ShiroUtil.delectSession(user.getLoginAccount());
            }else{
                ShiroUtil.updateSession(user.getLoginAccount());
            }
        }
        return bol;
    }
    /**
     * 修改密码
     * @param user
     * @return
     */
    @Override
    public int updatePassword(User user, String newPassword) {

        User users = getUser(user.getUserId());

        if(ShiroUtil.password(user).equals(users.getPassword())){
            user.setPassword(newPassword);
            users.setPassword(ShiroUtil.password(user));
            return updateUser(users)==true?0:1;

        }
        return 2;
    }

    /**
     * 批量修改用户信息
     * @param userIds
     * @param user
     * @return
     */
    @Override
    public boolean updateUser(List<String> userIds, User user) {
        UserExample example = new UserExample();
        example.createCriteria().andUserIdIn(userIds);
        return userMapper.updateByExampleSelective(user,example) > 0;
    }

    /**
     * 通过用户ID获取用详情及用户角色权限信息（状态正常角色权限）
     * @param userId
     * @return
     */
    @Override
    public UserAndRoleAndPermission getUserIdAndRoleAndPermission(String userId) {
        return userAndRoleAndPermissionMapper.selectByPrimaryKey(userId);
    }

    @Override
    public List<UserAndRoleAndPermission> getUserAndRoleAndPermission(String perId) {
        UserAndRoleAndPermissionExample example = new UserAndRoleAndPermissionExample();
        example.createCriteria().andPerIdEqualTo(perId);
        return userAndRoleAndPermissionMapper.selectByExample(example);
    }

    /**
     * 通过用户ID(类型)获取用详情及用户角色权限信息(权限角色为正常状态)
     * @param userId
     * @param route
     * @return
     */
    @Override
    public UserAndRoleAndPermission getUserAndRoleAndPermission(String userId, String route,String url) {

        DiyTypeAndDictionary diyTypeAndDictionary = diyTypeAndDictionaryService.getDiyTypeAndDictionary(route);

        if(null != diyTypeAndDictionary){

            if(ListUtil.isNotList(diyTypeAndDictionary.getDictionaryList())){

                List<Dictionary> dictionaries = diyTypeAndDictionary.getDictionaryList();

                UserAndRoleAndPermissionExample example = new UserAndRoleAndPermissionExample();
                UserAndRoleAndPermissionExample.Criteria criteria = example.createCriteria();

                if(StringUtils.isNotBlank(userId)){

                    criteria.andUserIdEqualTo(userId);

                }

                if(ListUtil.isNotList(dictionaries)){

                    criteria.andTypeIn(ListUtil.getFieldValues(dictionaries,"dictionaryRoute"));

                }

                if(StringUtils.isNotBlank(url)){
                    List<Permission> list = permissionService.getPermissionIdList(url);
                    if(ListUtil.isNotList(list)){
                        criteria.andParentIdIn(ListUtil.getFieldValues(list,"perId"));
                    }
                }

                if(criteria.isValid()){

                    criteria.andRoleIsStateEqualTo(Constant.SUCCESS).andPermissionIsStateEqualTo(Constant.SUCCESS);
                    example.setOrderByClause(" p.stort ASC");
                    List<UserAndRoleAndPermission> userAndRoleAndPermissions = userAndRoleAndPermissionMapper.selectByExample(example);

                    if(ListUtil.isNotList(userAndRoleAndPermissions)){
                        return userAndRoleAndPermissions.get(0);
                    }

                }

            }

        }

        return null;

    }

    /**
     * 获取用户的角色及部门
     * @param userId
     * @return
     */
    @Override
    public UserAndRoleAndPermission getUserRoleDept(String userId,boolean bvol) {
        //获取当前用户的角色部门信息
        UserAndRoleAndPermission userAndRoleAndPermission = userAndRoleAndPermissionMapper.selectByUserRolePrimaryKey(userId);

        if(null != userAndRoleAndPermission){
            List<Role> userRoleList = new ArrayList<>();
            if(ListUtil.isNotList(userAndRoleAndPermission.getRoleList())){
                userRoleList =userAndRoleAndPermission.getRoleList();
            }
            //获取所有正常的角色信息
            List<Role> roleList = roleService.getRole(Constant.SUCCESS);

            if(ListUtil.isNotList(roleList)){

                //取出当前用户的角色id
                List<String> userRoleId = ListUtil.getFieldValues(userRoleList,"roleId");
                //取出当前用户的角色父级id
                List<String> userRoleParentId = ListUtil.getFieldValues(userRoleList,"parentId");

                List<Tree<Role>> trees = new ArrayList<Tree<Role>>();

                //循环添加tree树结构
                for (Role role : roleList){

                    Tree<Role> tree = new Tree<Role>();

                    tree.setId(role.getRoleId());

                    tree.setParentId(role.getParentId());

                    tree.setText(role.getRoleName());

                    //存放节点状态
                    Map<String, Object> state = new HashMap<>();

                    //获取角色id并判断当前用户是否包含此角色
                    String roleId = role.getRoleId();

                    if(bvol){

                        if (userRoleId.contains(roleId)) {

                            if(userRoleParentId.contains(roleId)){

                                state.put("undetermined",true);

                            }else{

                                state.put("selected", true);

                            }

                        }else{

                            state.put("selected", false);

                        }

                    }else {

                        if (userRoleId.contains(roleId)) {

                            state.put("selected", true);

                        } else {

                            continue;

                        }

                    }

                    tree.setState(state);

                    trees.add(tree);

                }
                // 默认顶级菜单为０，根据数据库实际情况调整
                Tree<Role> t = BuildTreeUtil.build(trees);

                userAndRoleAndPermission.setRoleTree(t.getChildren());
            }

        }
        return userAndRoleAndPermission;
    }

    /**
     * 获取用户的部门
     * @param userId
     * @return
     */
    @Override
    public UserAndRoleAndPermission getUserDept(String userId) {
        return userAndRoleAndPermissionMapper.selectByUserDeptPrimaryKey(userId);
    }

    /**
     * 修个用户头像
     * @param file
     * @return
     */
    @Override
    public boolean updatUserImg(MultipartFile file){
        try{
            String url = uploadService.upload(file,"user");
            User user = TokenUtil.getToken();
            user.setImg(url);
            return updateUser(user);
        }catch (Exception e){
            return false;
        }

    }

}
